package items;

import main.Map;

import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Polygon;

import blocks.Block;

import shared.Timer;

import entities.Player;

public abstract class Item {
	private int id;
	private Image texture;
	private int x;
	private int y;
	private int width;
	private int height;
	private int currentFallSpeed;
	private int maxFallSpeed;
	private int fallSpeedIncrement;
	private Polygon polygon;
	
	private String type;
	private int count;
	private boolean isSelected;
	private boolean isInInventory;
	private boolean justDropped;
	private Timer dropTimer;
	
	public abstract void use(GameContainer gc, Player player) throws SlickException;
	
	public Item(int id, int x, int y, int width, int height) {
		this.id = id;
		this.x = x;
		this.y = y;
		this.width = width;
		this.height = height;
		type = "";
		isInInventory = false;
		isSelected = false;
		justDropped = false;
		count = 1;
		
		maxFallSpeed = 25;
		currentFallSpeed = 0;
		fallSpeedIncrement = 1;
		dropTimer = new Timer(2);
		dropTimer.resetTimer();
		
		polygon = new Polygon(new float[] {x, y,
										   x + width, y,
										   x + width, y + height,
										   x, y+ height});
	}

	public void update() {
		if(!isInInventory) {
			fall();
			
			//Time before it can be picked up again
			if(justDropped) {
				boolean dropTimeOver = dropTimer.update();
				
				if(dropTimeOver) {
					dropTimer.resetTimer();
					justDropped = false;
				}
			}
			
			//polygon
			updatePolygon();
		}
	}
	
	private void updatePolygon() {
		polygon = new Polygon(new float[] {x, y,
				   x + width, y,
				   x + width, y + height,
				   x, y+ height});
	}

	private void fall() {
		if(currentFallSpeed < maxFallSpeed) {
			currentFallSpeed += fallSpeedIncrement;
		}
		
		//Fall
		if(!collidedWithBlock(0, currentFallSpeed)) {
			setY(getY() + currentFallSpeed);
		} else {
			currentFallSpeed = 0;
		}
	}
	
	private boolean collidedWithBlock(int polX, int polY) {
		boolean cl = false;
		Block b = Map.getBlock(getX() + polX, getY() + polY);
		if(b != null) {
			cl = true;
		}
		
		b = Map.getBlock(getX() + getWidth() + polX, getY() + polY);
		if(b != null) {
			cl = true;
		}
		
		b = Map.getBlock(getX() + getWidth() + polX, getY() + getHeight() + polY);
		if(b != null) {
			cl = true;
		}
		
		b = Map.getBlock(getX() + polX, getY() + getHeight() + polY);
		if(b != null) {
			cl = true;
		}
		
		return cl;
	}

	public void draw(Graphics g) {
		if(texture != null) {
			g.drawImage(texture, x, y);
			if(isInInventory)
				g.drawString(Integer.toString(count), x, y);
		}
	}
	
	public Item getItem() {
		return this;
	}

	public Image getTexture() {
		return texture;
	}

	public void setTexture(String texture) throws SlickException {
		this.texture = new Image(texture);
	}

	public int getX() {
		return x;
	}

	public void setX(int x) {
		this.x = x;
	}

	public int getY() {
		return y;
	}

	public void setY(int y) {
		this.y = y;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public int getCount() {
		return count;
	}

	public void setCount(int count) {
		this.count = count;
	}

	public boolean isSelected() {
		return isSelected;
	}

	public void setSelected(boolean isSelected) {
		this.isSelected = isSelected;
	}
	
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}
	
	public int getWidth() {
		return width;
	}

	public void setWidth(int width) {
		this.width = width;
	}

	public int getHeight() {
		return height;
	}

	public void setHeight(int height) {
		this.height = height;
	}
	
	public boolean isJustDropped() {
		return justDropped;
	}

	public void setJustDropped(boolean justDropped) {
		this.justDropped = justDropped;
	}

	public boolean isInInventory() {
		return isInInventory;
	}

	public void setInInventory(boolean isInInventory) {
		this.isInInventory = isInInventory;
	}

	public Polygon getPolygon() {
		return polygon;
	}

	public void setPolygon(Polygon polygon) {
		this.polygon = polygon;
	}
}
